package com.golang.api.controller;

import com.golang.api.domain.User;
import com.golang.api.service.IUserService;
import com.golang.api.util.CommonUtil;
import com.golang.api.util.JWTUtil;
import com.golang.api.util.Result;
import com.golang.api.util.ResultGenerator;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IUserService userService;

    /**
     * 微信登录，根据前端传来的code和phoneNum返回openid，token和sessionkey
     * @param code
     * @param phoneNum
     * @return
     */
    @RequestMapping("/login")
    public Result<Map<String, String>> wxLogin(@RequestParam String code, @RequestParam String phoneNum) {
        String jsonResponse = userService.getOpenIdByCode(code);
        JsonObject jsonObject = JsonParser.parseString(jsonResponse).getAsJsonObject();
        log.info("用户登录:{}", jsonObject);
        String openId = jsonObject.get("openid").getAsString();
        String sessionKey = jsonObject.get("session_key").getAsString();

        //用openId生成token，有效期3天
        String token = JWTUtil.geneJsonWebToken(openId);

        //把token放到redis里
        redisTemplate.opsForValue().set(token, openId, Duration.ofDays(3));

        //把openId放到数据库里，先根据PhoneNum查找用户，若查到，则更新openId，若没查到，则插入一条数据
        if(userService.selectUserByPhoneNum(phoneNum)) {
            //查到用户，更新用户的open id
            userService.updateUserOpenId(openId, phoneNum);
        } else {
            //没查到用户，创建新用户插入
            User user = new User();
            user.setOpenId(openId);
            user.setPhone(phoneNum);
            userService.addNewUser(user);
        }
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("token", token);
        resultMap.put("openId", openId);
        resultMap.put("sessionKey", sessionKey);

        return ResultGenerator.result(0, "登录成功", resultMap);
    }

    /**
     * 静默登录接口，根据openId查询用户，返回用户数
     * @param openId
     * @return
     */
    @RequestMapping("/checkLogin")
    public Result<String> getUserByOpenId(@RequestParam String openId) {
        int userNum = userService.getUserByOpenId(openId);
        return ResultGenerator.result(0, "查询成功", String.valueOf(userNum));
    }

    /**
     * 根据传入的手机号发送验证码，验证码发送不稳定，请勿使用，仅供测试使用
     * @param phoneNum
     * @return
     */
    @RequestMapping("/sendCode")
    public Result<String> sendCode(@RequestParam String phoneNum) {
        log.info("手机号：{}", phoneNum);
        String code = CommonUtil.getRandomCode(6);
        log.info("验证码：{}", code);
        //有效期设为5分钟
        redisTemplate.opsForValue().set(phoneNum, code, Duration.ofMinutes(5));

        //验证码发送短信给用户
        userService.sendTextCodeByPhoneNum(phoneNum, code);

        return ResultGenerator.result(200, "验证码发送成功", code);
    }

    /**
     * 用户使用手机号和验证码登录，同时绑定用户与手机号
     * @param phoneNum
     * @param code
     * @return
     */
    @RequestMapping("/bind")
    public Result<String> login(@RequestParam String phoneNum, @RequestParam String code) {
        String redisCode = (String) redisTemplate.opsForValue().get(phoneNum);
        if (redisCode.equals(code)) {
            //在用户信息中添加手机号,即在数据库中插入一条数据，自动生成用户名，保存手机号
            if (!userService.selectUserByPhoneNum(phoneNum)) {
                userService.addNewUser(phoneNum);
                return ResultGenerator.result(200, "注册成功", "");
            }
            return ResultGenerator.result(200, "登录成功", "");
        } else {
            return ResultGenerator.result(500, "注册或登录失败", "");
        }
    }
}
